#pragma once

#include <boost/shared_ptr.hpp>
#include <boost/noncopyable.hpp>
#include <services/scheduler.hpp>
#include <logger/stream.hpp>

#include "exports.hpp"
#include "DataProcessor.h"




/**
 * The Scheduler is responsible for executing a set of DataProcessors.
 */
class CRAWLER_API Scheduler
	: public boost::noncopyable
{
public:

	typedef boost::shared_ptr<Scheduler>             Ptr;
	typedef boost::shared_ptr<const Scheduler>       const_Ptr;

	typedef QPair<services::task::ptr, DataProcessor::Ptr>   TaskProc;
	typedef QList<TaskProc>                                  Tasks;

private:

	services::scheduler::ptr   m_scheduler;
	logger::stream::ptr        m_logger;
	Tasks                      m_tasks;
	std::size_t                m_maxExceptions;

public:

	Scheduler(services::provider::const_ptr provider);
	virtual ~Scheduler();



	/**
	 * Adds the given processor to this scheduler.
	 * It will not be executed until start is called.
	 */
	void add(DataProcessor::Ptr processor);



	/**
	 * Starts the scheduler, ie. starts the configured number of threads
	 * and distributes the data processors among them.
	 * Returns when all threads have been started.
	 */
	void start();

	/**
	 * Stops the scheduler and all managed threads.
	 * Returns when all threads have been stopped.
	 */
	void stop();

private:

	/**
	 * Runs one step of the given processor.
	 */
	void run_processor(DataProcessor::Ptr processor);
};
///////////////////////////////////////////////////////////////////////////////////////////////////
